﻿using System.Windows.Input;
using Azukit.Messaging;
using Azukit.WPF.Command;
using Azukit.WPF.ViewModel;
using Hibiku.Helpers;
using Hibiku.Services;
using Hibiku.Twitter;

namespace Hibiku.ViewModels
{
    public class TweetComposerViewModel : ViewAwareViewModelBase, ITransceiverOwner
    {
        public class TweetSentMessage { }

        public ICommand SendCommand { get; private set; }
        public ICommand ToggleLocationCommand { get; private set; }
        public ICommand ShowLocationCommand { get; private set; }

        private Location _location;
        public Location Location
        {
            get { return _location; }
            private set
            {
                _location = value;
                FirePropertyChanged(() => Location);
                FirePropertyChanged(() => HasLocation);
            }
        }

        public bool HasLocation
        {
            get { return Location != null; }
        }

        private string _tweetText = "";
        public string TweetText
        {
            get { return _tweetText; }
            set
            {
                if (value != null)
                {
                    _tweetText = value;
                    FirePropertyChanged(() => TweetText);
                    FirePropertyChanged(() => IsValid);
                }
            }
        }

        public bool IsValid
        {
            get
            {
                var length = (TweetText ?? string.Empty).Length;

                return length > 0 && length <= 140;
            }
        }

        private readonly IGeoLocatorService _locatorService;
        private readonly ITwitterApi _twitterApi;

        private bool _locationToggled = false;
        private Tweet _replyingTo = null;

        public TweetComposerViewModel(
            ITransceiver transceiver,
            IGeoLocatorService locatorService,
            ITwitterApi twitterApi)
        {
            _transceiver = transceiver;
            _locatorService = locatorService;
            _twitterApi = twitterApi;

            _locatorService.LocationFound += HandleLocationFound;

            SendCommand = new DelegatingCommand((x) => Send(), (x) => CanSend());
            ToggleLocationCommand = new DelegatingCommand(x => ToggleLocation());
            ShowLocationCommand = new DelegatingCommand(x => ShowLocation());

            Transceiver.Listen<Tweet>(HandleTweetMessage);
        }

        private void HandleTweetMessage(Tweet tweet)
        {
            _replyingTo = tweet;

            TweetText = string.Format("@{0} ", tweet.User.ScreenName);
        }

        private void HandleLocationFound(double lat, double lon)
        {
            if (_locationToggled)
            {
                Location = new Twitter.Location(lat, lon);
            }
        }

        private void Send()
        {
            var inReplyToStatusId = (_replyingTo == null ? (long?)null : _replyingTo.Id);

            _twitterApi.Update(TweetText, inReplyToStatusId, Location);

            TweetText = "";

            Transceiver.Send(new TweetSentMessage());
        }

        private bool CanSend()
        {
            return IsValid;
        }

        private void ToggleLocation()
        {
            if (!_locationToggled)
            {
                _locationToggled = true;

                _locatorService.Locate();
            }
            else
            {
                _locationToggled = false;

                Location = null;
            }
        }

        private void ShowLocation()
        {
            UrlHelper.OpenLocation(Location);
        }

        #region ITransceiverOwner Members

        private readonly ITransceiver _transceiver;
        public ITransceiver Transceiver
        {
            get { return _transceiver; }
        }

        #endregion
    }
}
